package com.ushine.web.base.init;


import com.ushine.web.base.model.system.UserDO;
import com.ushine.web.base.service.IUserService;
import com.ushine.web.communication.netty.NettySocketServer;
import com.ushine.web.communication.tcp.NettyWebsocketServer;
import com.ushine.web.communication.threads.CommunicationThreads;
import com.ushine.web.component.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;


/**
 * @Author yls
 * @Date 2020/3/30 21:23
 * @Description 需要在容器启动的时候执行一些内容。比如读取配置文件，
 * 数据库连接之类的。SpringBoot给我们提供了两个接口来帮助我们实现这种需求。
 * 这两个接口分别为CommandLineRunner和ApplicationRunner。
 * 他们执行时机为容器启动完成的时候。
 * @Version 1.0
 **/
@Component
@Order(1)
@Slf4j
public class BaseApplicationRunner implements ApplicationRunner {

    private static final String TAG = "项目初始化=》";

    @Resource
    private IUserService userService;

    @Resource
    private NettySocketServer nettySocketServer;

    @Resource
    private NettyWebsocketServer nettyWebsocketServer;


    @Resource
    private CommunicationThreads communicationThreads;

    /**
     * 功能描述:
     * 〈web业务系统初始化的主要方法〉
     *
     * @param args app的参数
     * @return : void
     * @author : yls
     * @date : 2020/07/12 10:54
     */
    @Override
    public void run(ApplicationArguments args) throws ServiceException, InterruptedException {
        System.setProperty("io.netty.noUnsafe", "true");
        // 初始化 netty-websocket 通信
        log.info("{}初始化 netty-websocket 通信--start", TAG);
        Runnable websocketRunnable = () -> {
            try {
                nettyWebsocketServer.initServer();
            } catch (InterruptedException e) {
                log.error("{}初始化 netty-websocket 失败!", TAG, e);
                Thread.currentThread().interrupt();
            }
        };
        CommunicationThreads.EXECUTOR.execute(websocketRunnable);
        log.info("{}初始化 netty-websocket 通信--end", TAG);

        // 初始化 netty-socket通信
        log.info("{}初始化 netty-socket 通信--start", TAG);
        Runnable socketRunnable = () -> {
            try {
                nettySocketServer.initServer();
            } catch (InterruptedException e) {
                log.error("{}初始化 netty-socket失败!", TAG, e);
                Thread.currentThread().interrupt();
            }
        };
        CommunicationThreads.EXECUTOR.execute(socketRunnable);
        log.info("{}初始化 netty-socket 通信--end", TAG);


        //获取项目启动携带的参数
        UserDO admin = userService.getUserBaseInfo("admin");
        if (admin == null) {
            log.info("{}初始化系统超级管理员--start", TAG);
            UserDO userDO = new UserDO();
            userDO.setUsername("admin");
            userDO.setTrueName("超级管理员");
            userDO.setAccountNonExpired(true);
            userDO.setAccountNonLocked(true);
            userDO.setCredentialsNonExpired(true);
            userDO.setEnabled(true);
            userService.insertUser(userDO);
            log.info("{}初始化系统超级管理员--success--end", TAG);
        }
    }
}
